/**
 * Electron 文件操作适配器
 * 使用 Electron API 替代直接的 Node.js 文件系统调用
 */

import type { 
  FileOperations, 
  FileStats, 
  CopyOperation, 
  BatchResult, 
  FailedOperation,
  AppError
} from '../types'
import { ErrorType } from '../types/errors'



export class ElectronFileOperationsImpl implements FileOperations {
  private maxConcurrentOperations: number

  constructor(maxConcurrentOperations: number = 5) {
    this.maxConcurrentOperations = maxConcurrentOperations
  }

  /**
   * 读取文件内容
   */
  async readFile(filePath: string): Promise<string> {
    try {
      const resolvedPath = window.pathAPI.resolve(filePath)
      const result = await window.electronAPI.readFile(resolvedPath)
      
      if (!result.success) {
        throw new Error(result.error || 'Unknown error')
      }
      
      return result.content || ''
    } catch (error) {
      throw this.createError(
        ErrorType.FILE_NOT_FOUND,
        `Failed to read file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
      )
    }
  }

  /**
   * 写入文件
   */
  async writeFile(filePath: string, content: string): Promise<void> {
    try {
      const resolvedPath = window.pathAPI.resolve(filePath)
      const result = await window.electronAPI.writeFile(resolvedPath, content)
      
      if (!result.success) {
        throw new Error(result.error || 'Unknown error')
      }
    } catch (error) {
      throw this.createError(
        ErrorType.UNKNOWN_ERROR,
        `Failed to write file ${filePath}: ${error instanceof Error ? error.message : String(error)}`
      )
    }
  }

  /**
   * 复制文件
   */
  async copyFile(sourcePath: string, targetPath: string): Promise<void> {
    try {
      const resolvedSource = window.pathAPI.resolve(sourcePath)
      const resolvedTarget = window.pathAPI.resolve(targetPath)
      
      // 检查源文件是否存在
      const sourceExists = await this.fileExists(resolvedSource)
      if (!sourceExists) {
        throw this.createError(
          ErrorType.FILE_NOT_FOUND,
          `Source file does not exist: ${sourcePath}`
        )
      }
      
      const result = await window.electronAPI.copyFile(resolvedSource, resolvedTarget)
      
      if (!result.success) {
        throw new Error(result.error || 'Unknown error')
      }
    } catch (error) {
      if (error instanceof Error && 'type' in error) {
        throw error
      }
      throw this.createError(
        ErrorType.UNKNOWN_ERROR,
        `Failed to copy file from ${sourcePath} to ${targetPath}: ${error instanceof Error ? error.message : String(error)}`
      )
    }
  }

  /**
   * 创建目录（通过写入临时文件实现）
   */
  async ensureDirectory(dirPath: string): Promise<void> {
    try {
      // Electron API 会在写入文件时自动创建目录
      // 这里我们不需要单独的目录创建操作
    } catch (error) {
      throw this.createError(
        ErrorType.UNKNOWN_ERROR,
        `Failed to create directory ${dirPath}: ${error instanceof Error ? error.message : String(error)}`
      )
    }
  }

  /**
   * 检查文件是否存在
   */
  async fileExists(filePath: string): Promise<boolean> {
    try {
      const resolvedPath = window.pathAPI.resolve(filePath)
      const result = await window.electronAPI.readFile(resolvedPath)
      return result.success
    } catch {
      return false
    }
  }

  /**
   * 获取文件统计信息
   */
  async getFileStats(filePath: string): Promise<FileStats> {
    try {
      const resolvedPath = window.pathAPI.resolve(filePath)
      const result = await window.electronAPI.readFile(resolvedPath)
      
      if (!result.success) {
        throw new Error(result.error || 'File not found')
      }
      
      return {
        size: result.size || 0,
        modifiedTime: result.mtime || new Date(),
        isDirectory: false // 简化实现，假设都是文件
      }
    } catch (error) {
      throw this.createError(
        ErrorType.FILE_NOT_FOUND,
        `Failed to get file stats for ${filePath}: ${error instanceof Error ? error.message : String(error)}`
      )
    }
  }

  /**
   * 批量复制文件
   */
  async batchCopyFiles(operations: CopyOperation[]): Promise<BatchResult> {
    const successful: CopyOperation[] = []
    const failed: FailedOperation[] = []
    
    // 使用并发控制处理批量操作
    const chunks = this.chunkArray(operations, this.maxConcurrentOperations)
    
    for (const chunk of chunks) {
      const promises = chunk.map(async (operation) => {
        try {
          // 检查是否需要覆盖
          if (!operation.overwrite) {
            const targetExists = await this.fileExists(operation.targetPath)
            if (targetExists) {
              throw new Error('Target file already exists and overwrite is disabled')
            }
          }
          
          await this.copyFile(operation.sourcePath, operation.targetPath)
          successful.push(operation)
        } catch (error) {
          failed.push({
            ...operation,
            error: error instanceof Error ? error.message : String(error)
          })
        }
      })
      
      // 等待当前批次完成
      await Promise.allSettled(promises)
    }
    
    return {
      successful,
      failed,
      totalCount: operations.length
    }
  }

  /**
   * 将数组分块以控制并发
   */
  private chunkArray<T>(array: T[], chunkSize: number): T[][] {
    const chunks: T[][] = []
    for (let i = 0; i < array.length; i += chunkSize) {
      chunks.push(array.slice(i, i + chunkSize))
    }
    return chunks
  }

  /**
   * 创建错误对象
   */
  private createError(type: ErrorType, message: string): AppError {
    return {
      type,
      message,
      timestamp: new Date(),
      recoverable: type !== ErrorType.UNKNOWN_ERROR
    }
  }
}

// 检查是否在 Electron 环境中
const isElectron = typeof window !== 'undefined' && window.electronAPI

// 导出适当的实例
export const fileOperations = isElectron 
  ? new ElectronFileOperationsImpl()
  : null // 在非 Electron 环境中返回 null